home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr47 / 80x0393.zip / ADLIB.TXT next >
Text File  |  1993-06-20  |  8KB  |  154 lines

  1. By: Emil Gilliam
  2. Re: adlib digitized sound
  3. ------------------------------------------------------------------------
  4.  
  5. Okay, here we go with some specifics on how to play digitized sound  out 
  6. of the AdLib!  Note:  If you write a program that uses sound boards, you 
  7. should make it recognize the Sound Blaster and use the Sound Blaster DAC 
  8. if  there is one, because it sounds better, so I suggest that  you  only 
  9. use  this method for playing digitized sound out of the AdLib  if  there 
  10. actually  is  a real AdLib.  (Also, I don't know if  this  method  works 
  11. right  on the Sound Blaster, so if there's a Sound Blaster, use the  DAC 
  12. instead!!)
  13.  
  14. Here's how to play a digitized sample out of the AdLib:
  15.  
  16. 1.) Disable interrupts.  (While we change vectors and things)
  17.  
  18. 2.)  Get  the old interrupt 8 vector and save it.  Set the  interrupt  8 
  19. vector to point to a new interrupt 8 handler (which is described below).  
  20. I  suggest  that you get and set interrupt vectors yourself  instead  of 
  21. calling DOS to do it, because maybe DOS tries to hook itself into  every 
  22. vector  somehow (?) and that can be a problem when our new  interrupt  8 
  23. vector will be called thousands of times a second.
  24.  
  25. 3.)  Okay,  now we're going to set up the AdLib  for  playing  digitized 
  26. sound. As many of you know, the AdLib uses I/O ports 388h and 389h (388h 
  27. is the index register, 389h is the data, and 389h is write-only).
  28.  
  29. Note:  After you write a register number to port 388h, you need to  wait 
  30. 3.3  microseconds for the card to respond.  After you write a  value  to 
  31. one  of  the registers at port 389h, you need to  wait  23  microseconds 
  32. before you can write to another register.  You can wait 3.3 microseconds 
  33. by doing 6 "IN AL,DX" instructions from port 388h, (I think that each IN 
  34. AL,DX  from port 388h will take the same amount of time no  matter  what 
  35. the  speed of the computer is [?] because it takes the card a  while  to 
  36. get the value of the status register of the AdLib, which is what you get 
  37. when  you  read  from port 388h.  But we don't need the  value  of  that 
  38. status  register, we just need to IN AL,DX from it 6 times for  the  3.3 
  39. microsecond  wait.)   You can wait the 23 microseconds by doing  35  "IN 
  40. AL,DX"  instructions  from port 388h.  By the way, you  should  put  all 
  41. these  IN AL,DX's in a row rather that in a loop, because the loop  will 
  42. take time and you'll wait more time than necessary.
  43.  
  44. Here's how to set up the AdLib card for playing digitized sound.   Write 
  45. 21h to register 20h (Sets MULTI=1,AM=0,VIB=0,KSR=0,EG=1 for operator 1).  
  46. Then  write 0F0h to register 60h (Sets attack rate to 15 and decay  rate 
  47. to 0 for operator 1, makes sense because we want the sine wave to  start 
  48. immediately and we never want it to stop), and write 0F0h to register 80h 
  49. (sets the sustain level to 15 and the release rate to 0 for operator 1).
  50.  
  51. Then, write 01h to register 0C0h.  (Feedback=0 and Additive Synthesis is 
  52. on  for voice 1 [which is operator 1 and operator 4]).  Then write 0  to 
  53. register 0E0h.  (Waveform=regular sine wave for operator 1.)  Then write 
  54. 3Fh to register 43h (sets total level=63 and attenuation for operator 4, 
  55. don't  ask me why this is done, but I do know that operator  4  combines 
  56. with operator 1 to make one of the voices).
  57.  
  58. Then write 1 to register 0B0h.
  59. Then write 8Fh to register 0A0h.
  60. Then write 2Eh to register 0B0h.  (Set KEY ON)
  61. (I don't know why we have the multiple writes to register 0B0h.
  62.  
  63. This sets the frequency of operator 1, the speed of the sine wave.
  64.  
  65. 4.)  Immediately  (right  after  writing  2Eh  to  register  0B0h,   and 
  66. interrupts  are still disabled), wait until 952h 8253 timer  ticks  have 
  67. passed.   I  think that what this does is wait for the sine  wave  being 
  68. generated by operator 1 to get all the way to the top.
  69.  
  70. 5.)  Now that the sine wave of operator 1 is at the top, we're  immedia
  71. tely going to change the frequency of operator 1 to 0, so that the  sine 
  72. wave  is  stuck at the top.  Write 20h to register 0B0h and write  0  to 
  73. register  0A0h.  The  20h in register 0B0h keeps operator  1  in  KEY-ON 
  74. state.
  75.  
  76. 6.)  We're  almost  done setting up.  Divide 1193180 by  the  number  of 
  77. samples  per  second and write that value into timer channel 0  (of  the 
  78. 8253 chip). This will change the number of times per second interrupt  8 
  79. is called to the number of samples per second.  Interrupt 8 is going  to 
  80. be  called for each sample, and it will play one sample each  time  it's 
  81. called.
  82.  
  83. 7.) Enable interrupts, and wait until the sample is done playing.  (Your 
  84. interrupt 8 handler should set some sort of flag when it's done.)
  85.  
  86. 8.)  Disable interrupts, set the interrupt 8 vector to what it  used  to 
  87. be, write 0 to 8253 timer channel 0 (to make interrupt 8 go 18.2 times a 
  88. second), and we're done!
  89.  
  90. -----
  91.  
  92. Okay.  The new interrupt 8 handler should do this.
  93.  
  94. 1.)  Save any used registers.  (I know that the CPU will probably be  in 
  95. the waiting loop when interrupt 8 is called, and the waiting loop  might 
  96. use no registers, but save registers just to be on the safe side because 
  97. the  CPU  might be in the middle of processing a keyboard  interrupt  or 
  98. something like that.)
  99.  
  100. 2.) Get a 6-bit sample from the digitized sound sample.  (If you have an 
  101. 8-bit  sample, just shift each sample right two bits.  I assume  that'll 
  102. be the case because you can write a program to play digitized sound that 
  103. writes  values to the Sound Blaster DAC if there is a Sound Blaster  and 
  104. use  this method if there is an AdLib.)  Write that number  to  register 
  105. 40h.  (The top 2 bits should be 0).
  106.  
  107. Note:  An  alternative is to have the initialization code write  40h  to 
  108. port  388h  right  before enabling interrupts, and  then  all  that  the 
  109. interrupt  8 handler has to do is write values to port 389h  instead  of 
  110. having to write 40h to port 388h every time.
  111.  
  112. 3.)  Write  20h to port 20h (8259 non-specific EOI),  restore  any  used 
  113. registers, and get the heck outta there with IRET.
  114.  
  115. -----
  116.  
  117. The  only  problem with this is that the computer's clock will  be  held 
  118. while  the  sample  is playing, because the regular  interrupt  8  isn't 
  119. executing  while the sample is playing, but if that's a problem you  can 
  120. circumvent that yourself by getting the length of the sample and  adding 
  121. that to the computer's time when you're done, or by possibly getting the 
  122. CMOS  time.  That's  something  I still don't know,  on  AT's  does  the 
  123. computer  get the time from the CMOS whenever you have to get the  time, 
  124. or  does  the computer just get the time on bootup and write  that  into 
  125. some  low-memory  address for interrupt 8 to increase  every  time  it's 
  126. called?   On AT's, does interrupt 8 even increase any time variables  at 
  127. all?  Does it need to?  If anyone knows anything about that, please  let 
  128. me know.
  129.  
  130. -----
  131.  
  132.    The  playing of digitized sound out of the AdLib doesn't have to  use 
  133. operator  1,  it  can use any operator.  It just has  to  use  the  same 
  134. operator  all  the  way  through.  (Except for when  you  write  3Fh  to 
  135. register  43h, don't ask me why that was in what I disassembled...   but 
  136. if you change operator numbers, you'll have to change this reference  to 
  137. operator  4 to the operator that the other one is "paired  up  with"...)  
  138. That means that you can play digitized sound and music at the same  time 
  139. out of the AdLib!  Just play digitized sound as usual and while  waiting 
  140. for  the  sample to play, use the other voices to play music!   You  can 
  141. even play two samples at the same time by using two different  operators 
  142. and  having  your interrupt 8 handler write values to  both!   Theoreti
  143. cally,  you can play as many samples as you want and music at  the  same 
  144. time...   I'm  sure  that in practice that would be VERY  hard  to  pull 
  145. off...  almost more trouble than it's worth... but maybe someone  should 
  146. give it a try!
  147.  
  148.  
  149. And  there  you have it.  I hope that THAT is pretty complete!   But  if 
  150. anyone still needs any more information, like on how to read or write to 
  151. the 8253 timer chip, let me know.                                                   
  152.                                                                            
  153.                                                 Emil Gilliam               
  154.